﻿using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;

namespace Gmantis.Controls.DataGrid
{
    public class DataGridCheckBoxColumn : DataGridBoundColumn
    {
        // Fields
        public static readonly DependencyProperty CheckedTextProperty = DependencyProperty.Register("CheckedText", typeof(string), typeof(DataGridCheckBoxColumn), new PropertyMetadata("Yes"));
        public static readonly DependencyProperty UncheckedTextProperty = DependencyProperty.Register("UncheckedText", typeof(string), typeof(DataGridCheckBoxColumn), new PropertyMetadata("No"));
        public static readonly DependencyProperty UndefinedTextProperty = DependencyProperty.Register("UndefinedText", typeof(string), typeof(DataGridCheckBoxColumn), new PropertyMetadata("Undefined"));

        // Methods
        public DataGridCheckBoxColumn()
        {
            this.Initialize();
        }

        public DataGridCheckBoxColumn(PropertyInfo property)
            : base(property)
        {
            this.Initialize();
        }

        public override bool BeginEdit(FrameworkElement editingElement, RoutedEventArgs routedEventArgs)
        {
            bool flag = false;
            if (((routedEventArgs is TextCompositionEventArgs) && (((TextCompositionEventArgs)routedEventArgs).Text == " ")) || (routedEventArgs is MouseButtonEventArgs))
            {
                flag = true;
            }
            if (!flag)
            {
                return false;
            }
            CheckBox box = (CheckBox)editingElement;
            if (base.AllowNull)
            {
                if (!box.IsChecked.HasValue)
                {
                    box.IsChecked = false;
                }
                else if (box.IsChecked.Value)
                {
                    box.IsChecked = null;
                }
                else
                {
                    box.IsChecked = true;
                }
            }
            else
            {
                bool? isChecked = box.IsChecked;
                box.IsChecked = new bool?(!(isChecked.HasValue ? isChecked.GetValueOrDefault() : false));
            }
            return true;
        }

        public override void BindCellContent(FrameworkElement cellContent, DataGridRow row)
        {
            CheckBox box = (CheckBox)cellContent;
            if (base.Binding != null)
            {
                Binding binding = base.CopyBinding(base.Binding, null);
                binding.Source = row.DataItem;
                box.SetBinding(ToggleButton.IsCheckedProperty, binding);
            }
            box.HorizontalAlignment = base.HorizontalAlignment;
            box.VerticalAlignment = base.VerticalAlignment;
            if (base.CellContentStyle != null)
            {
                box.Style = base.CellContentStyle;
            }
            else
            {
                box.Margin = new Thickness(4.0, 4.0, 4.0, 4.0);
            }
        }

        public override void CancelCellEdit(FrameworkElement editingElement, object uneditedValue)
        {
            ((CheckBox)editingElement).IsChecked = (bool?)uneditedValue;
        }

        public override FrameworkElement CreateCellContent(DataGridRow row)
        {
            return new CheckBox { IsHitTestVisible = false };
        }

        public override void EndEdit(FrameworkElement editingElement)
        {
            CheckBox box = editingElement as CheckBox;
            if (box != null)
            {
                BindingExpression bindingExpression = box.GetBindingExpression(ToggleButton.IsCheckedProperty);
                if (bindingExpression != null)
                {
                    bindingExpression.UpdateSource();
                }
            }
        }

        public override object GetCellContentRecyclingKey(DataGridRow row)
        {
            return typeof(CheckBox);
        }

        public override FrameworkElement GetCellEditingContent(DataGridRow row)
        {
            CheckBox box = new CheckBox
            {
                IsThreeState = base.AllowNull
            };
            if (base.Binding != null)
            {
                Binding binding = base.CopyBinding(base.Binding, null);
                box.SetBinding(ToggleButton.IsCheckedProperty, binding);
            }
            box.HorizontalAlignment = base.HorizontalAlignment;
            box.VerticalAlignment = base.VerticalAlignment;
            if (base.CellEditingContentStyle != null)
            {
                box.Style = base.CellEditingContentStyle;
            }
            return box;
        }

        public override string GetCellText(DataGridRow row)
        {
            FrameworkElement cellContent = this.CreateCellContent(row);
            this.BindCellContent(cellContent, row);
            string str = "";
            if (cellContent is CheckBox)
            {
                CheckBox box = cellContent as CheckBox;
                str = box.IsChecked.HasValue ? (box.IsChecked.Value ? this.CheckedText : this.UncheckedText) : this.UndefinedText;
            }
            this.UnbindCellContent(cellContent, row);
            return str;
        }

        public override IDataGridFilter GetFilter()
        {
            DataGridFilter filter = new DataGridFilter();
            DataGridCheckBoxFilter target = new DataGridCheckBoxFilter
            {
                IsThreeState = base.AllowNull
            };
            target.SetBinding<DataGrid>(Control.BackgroundProperty, base.DataGrid, dg => dg.HeaderBackground);
            target.SetBinding<DataGrid>(Control.ForegroundProperty, base.DataGrid, dg => dg.HeaderForeground);
            target.SetBinding<DataGrid>(Control.BorderBrushProperty, base.DataGrid, dg => dg.BorderBrush);
            filter.InnerControl = target;
            return filter;
        }

        private void Initialize()
        {
            base.HorizontalAlignment = HorizontalAlignment.Center;
            base.EditOnSelection = true;
        }

        public override object PrepareCellForEdit(FrameworkElement editingElement)
        {
            return ((CheckBox)editingElement).IsChecked;
        }

        // Properties
        public string CheckedText
        {
            get
            {
                return (string)base.GetValue(CheckedTextProperty);
            }
            set
            {
                base.SetValue(CheckedTextProperty, value);
            }
        }

        public override IValueConverter DefaultConverter
        {
            get
            {
                return new DataGridCheckBoxConverter(this);
            }
        }

        public override bool IsEditable
        {
            get
            {
                return (base.Binding != null);
            }
        }

        public string UncheckedText
        {
            get
            {
                return (string)base.GetValue(UncheckedTextProperty);
            }
            set
            {
                base.SetValue(UncheckedTextProperty, value);
            }
        }

        public string UndefinedText
        {
            get
            {
                return (string)base.GetValue(UndefinedTextProperty);
            }
            set
            {
                base.SetValue(UndefinedTextProperty, value);
            }
        }
    }
}
